#!/usr/bin/perl -w
use warnings;
use strict;

use utf8;

use FindBin qw($RealBin);

# Paths for installation
use lib ("$RealBin/..", "$RealBin/../lib");

# -------------------------------

# Standard Modules
use File::Find;
use File::Basename;
use Template;
use Data::Dumper;
use POSIX qw(strftime locale_h);
use IO::File;
use Getopt::Long;

$| = 1;

my $VERSION = '0.1';

my $VIDEOPATH = '/var/lib/video/.';
my $WWWPATH = '/var/www/xipodcast';
my $PODENCODER = sprintf('%s/xconvert', $RealBin);
my $XMLTEMPLATE = sprintf('%s/xipodcast.tmpl.xml', $RealBin);
my $SERVER = 'http://xpix.dieserver.de/webdav/xipodcast';
my $POSTCONVERT = sprintf('%s/xipodcast.post', $RealBin);
my $NONCONVERT = 0;

# Options
GetOptions (
  "version"      => \$VERSION,    # print version

  # Main Parameters (for Description see in $opt)
  "vpath"      => \$VIDEOPATH,
  "wwwpath"    => \$WWWPATH,
  "url"        => \$SERVER,
  "postc"      => \$POSTCONVERT,	
  "nonc"       => \$NONCONVERT,	
);

printf "No Convert is on!" if($NONCONVERT);

# Delete the running file in exit1
sub DESTROY {
   unlink '/tmp/xipodcast.running';
}

# create Template object
my $TT = Template->new({
    START_TAG    => '\<\?\%',		    # Tagstyle
    END_TAG      => '\%\?\>',		    # Tagstyle
    POST_CHOMP   => 1,               # cleanup whitespace 
    EVAL_PERL    => 1,               # evaluate Perl code blocks
    ABSOLUTE     => 1,
});

die 'Another prozess is running!' if(-e '/tmp/xipodcast.running');
my $erg = `touch /tmp/xipodcast.running`;

# Suche nach allen mp4 Files
my @f = glob($WWWPATH . '/*.mp4');
printf "Found %d mp4 files!\n", scalar @f;

my $oldmp4files = {};
foreach my $file (@f){
  $oldmp4files->{$file} = 1;
}

my $mp4files  = &searchIpodRecords($VIDEOPATH);
my $xml       = &createXML($mp4files);

# Lösche alle mp4 Files deren Aufnahmen 
# nicht mehr existieren
printf "Found %d mp4 files to delete!\n", 
  scalar keys %$oldmp4files;
unlink keys %$oldmp4files;

# Lösche bei Bedarf die Files auf einem SSH Server
system($POSTCONVERT, 'remove', keys %$oldmp4files) 
   if(-e $POSTCONVERT);

unlink '/tmp/xipodcast.running';

exit;

# ----------------------------- SUBS --------------------


#--------------------------------------------------------
sub searchIpodRecords {
#--------------------------------------------------------
  my $path = shift or error("No Path!");

  # Suche nach allen info.vdr
  my $erg = `find $path -name info.vdr`;
  my $mp4files = {};
  foreach my $file (split("\n", $erg)){
    next unless(-r $file);
    next if($file =~ /\.del/);
    next if(! -s dirname($file)."/index.vdr");
printf 'Qoutet File: %s %s', $file, "\n";
    my $search = `grep ipodcast "$file"`;
    chomp($search);
    if(($search or $file =~ /IPODC/) and (stat dirname($file)."/index.vdr")[9] < (time - 60)){
      my $infoData = &parseInfoFile($file);
      my $mp4file = &convert($file) or next;
      delete $oldmp4files->{$mp4file};
      $mp4files->{$mp4file} = $infoData;
      if(-s $mp4file < 1024) {
        my $erg = `$POSTCONVERT size $mp4file`;
        chomp($erg);
        if($erg) {
            $mp4files->{$mp4file}->{Length} = $erg;
        } else {
            delete $mp4files->{$mp4file};
        }
      } else {
        $mp4files->{$mp4file}->{Length} = -s $mp4file;
      }
      $mp4files->{$mp4file}->{Length} = -s $mp4file;
      $mp4files->{$mp4file}->{Base} = basename($mp4file);
    }    
  }
  return $mp4files;
}

#--------------------------------------------------------
sub convert {
#--------------------------------------------------------
  my $file = shift or error("No File in convert!");
  return if($NONCONVERT);
  
  my $videodir = dirname($file);
  $videodir =~ s/\'/\?/sig;
  $videodir =~ s/\&/\?/sig;
  $videodir =~ s/\(/\?/sig;
  $videodir =~ s/\)/\?/sig;

  my $md5 = `md5sum "$file"`;
  my $target = sprintf('%s/%s.mp4', $WWWPATH, (split(/ /, $md5))[0]);

  if(-e $target){
    `$POSTCONVERT $target` if(-e $POSTCONVERT);	
    return $target;	
  }

  printf "Convert: %s\n", $file;
  my $cmd = sprintf "%s %s/???.vdr", $PODENCODER, $videodir;

  printf "Call: %s\n", $cmd;
  my $erg = `$cmd`;
  my $source = sprintf('%s/tmp.mp4', dirname($file));
  return undef if(! -s $source);

  $erg = `mv "$source" "$target"`;

  return $target;  
}

#--------------------------------------------------------
sub createXML {
#--------------------------------------------------------
  my $mp4files = shift or error("No mp4File in createXML!");

  my $output;
  my $vars ={
    server => $SERVER,
    FILES => $mp4files,
    Builddate => convertTime(time),    
    Pubdate => convertTime(time),    
  };
  # process input template, substituting variables
  my $txt = $TT->process($XMLTEMPLATE, $vars, \$output)
      || error $TT->error();

  my $file = save_file( sprintf('%s/%s', $WWWPATH, 'xipodcast.xml'), $output);
  printf "CreatedXML: %s\n", $file;
  if(-e $file){
    `$POSTCONVERT $file` if(-e $POSTCONVERT);
  }

  return $txt;
}

#--------------------------------------------------------
sub parseInfoFile {
#--------------------------------------------------------
  my $file = shift or error("No File in convert!");
  my $ret = {};
  my $txt = `cat "$file"`;

  #C T-8468-258-14 Das Erste
  #E 10919 1227662100 6900 50 10
  #T Diebe wie wir
  #S Spielfilm USA 1973 (Thieves like us)
  #D Drei Häftlingen gelingt es, aus dem Staatsgefängnis von Mississippi zu entkommen. Gemeinsam überfallen sie danach mehrere Banken; mit dem erbeuteten Geld hoffen sie, eines Tages ein bürgerliches Leben führen zu können.
  #X 1 01 deu 4:3
  #X 2 02 deu zweikanal
  #V 1227662100

  ($ret->{Channel})   = $txt =~ /C\s+\S+\s+(.+?)\n/;
  ($ret->{Title})     = $txt =~ /\nT\s+(.+?)\n/;
  ($ret->{SubTitle})  = $txt =~ /\nS\s+(.+?)\n/;
  ($ret->{Descr})     = $txt =~ /\nD\s+(.+?)\n/;
  ($ret->{Time})     = $txt =~ /\nE\s+\d+\s+(\d+)\s+/;

  $ret->{Time} = convertTime($ret->{Time});

  foreach my $n (keys %$ret){
    if(defined $ret->{$n} and length($ret->{$n}) > 250){
      $ret->{$n} = substr($ret->{$n} , 0 , 250).'...';
    }
    $ret->{$n} = quote_xml_value($ret->{$n});
  }  

  return $ret;
}

#--------------------------------------------------------
sub convertTime {
#--------------------------------------------------------
  my $time = shift || time;

  my $timestr = scalar localtime( $time ); # Thu May  7 18:11:51 2009
  my($wday, $month, $day, $zeit, $year) = split(/\s+/, $timestr);
  my $daylight = strftime "%z", localtime($time);

  # Fri, 23 Jan 2009 19:31:02 +0100
  my $now_string = sprintf('%s, %02d %s %04d %s %s', 
    $wday, $day, $month, $year, $zeit, $daylight);


  return $now_string;  
}

#--------------------------------------------------------
sub error {
#--------------------------------------------------------
  my $msg = shift;
  unlink '/tmp/xipodcast.running';
  die $msg;
}

#--------------------------------------------------------
sub save_file {
#--------------------------------------------------------
	my $file = shift || return error('No file defined!');
	my $data = shift || '';

  return unless($file);

  my $mode = '>';

  my $fh = IO::File->new($file,$mode) 
    or return error(sprintf("Couldn't write %s : %s!",$file,$!));
  print $fh $data;
  $fh->close;

  return $file
}

sub quote_xml_value {
   my $value = shift || '';
   $value =~ s/([\x{80}-\x{10FFFF}])/'&#' . ord($1) . ';'/gse;
   $value =~ s/([\x{0}])/'&#' . ord($1) . ';'/gse;
   $value =~ s/^\s+|\s+$//g;

   return($value);
}


1;
